home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / blktiger.c < prev    next >
C/C++ Source or Header  |  2000-05-04  |  11KB  |  431 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7.   Video output ports:
  8.     ????? (3)
  9.         0x03 ?????
  10.  
  11.     Scroll page (0x0d)
  12.         Read/write scroll page number register
  13.  
  14.     Screen layout (0x0e)
  15.         Screen layout (8x4 or 4x8)
  16.  
  17. ***************************************************************************/
  18.  
  19. #include "driver.h"
  20. #include "vidhrdw/generic.h"
  21.  
  22. #include "osdepend.h"
  23.  
  24. unsigned char *blktiger_backgroundram;
  25. static unsigned char blktiger_video_control;
  26. unsigned char *blktiger_screen_layout;
  27. size_t blktiger_backgroundram_size;
  28. WRITE_HANDLER( blktiger_scrollx_w );
  29. WRITE_HANDLER( blktiger_scrolly_w );
  30. WRITE_HANDLER( blktiger_scrollbank_w );
  31.  
  32. static int blktiger_scroll_bank;
  33. static const int scroll_page_count=4;
  34. static unsigned char blktiger_scrolly[2];
  35. static unsigned char blktiger_scrollx[2];
  36. static unsigned char *scroll_ram;
  37. static unsigned char *dirtybuffer2;
  38. static struct osd_bitmap *tmpbitmap2;
  39. static struct osd_bitmap *tmpbitmap3;
  40. static int screen_layout;
  41. static int chon,objon,bgon;
  42.  
  43.  
  44.  
  45. /***************************************************************************
  46.  
  47.   Start the video hardware emulation.
  48.  
  49. ***************************************************************************/
  50.  
  51. int blktiger_vh_start(void)
  52. {
  53.     if (generic_vh_start() != 0)
  54.         return 1;
  55.  
  56.     if ((dirtybuffer2 = malloc(blktiger_backgroundram_size * scroll_page_count)) == 0)
  57.     {
  58.         generic_vh_stop();
  59.         return 1;
  60.     }
  61.     memset(dirtybuffer2,1,blktiger_backgroundram_size * scroll_page_count);
  62.  
  63.     if ((scroll_ram = malloc(blktiger_backgroundram_size * scroll_page_count)) == 0)
  64.     {
  65.         generic_vh_stop();
  66.         return 1;
  67.     }
  68.     memset(scroll_ram,0,blktiger_backgroundram_size * scroll_page_count);
  69.  
  70.  
  71.     /* the background area is 8 x 4 */
  72.     if ((tmpbitmap2 = osd_create_bitmap(8 * Machine->drv->screen_width,
  73.             scroll_page_count * Machine->drv->screen_height)) == 0)
  74.     {
  75.         free(dirtybuffer2);
  76.         generic_vh_stop();
  77.         return 1;
  78.     }
  79.  
  80.     /* the alternative background area is 4 x 8 */
  81.     if ((tmpbitmap3 = osd_create_bitmap(4 * Machine->drv->screen_width,
  82.             2 * scroll_page_count * Machine->drv->screen_height)) == 0)
  83.     {
  84.         free(dirtybuffer2);
  85.         osd_free_bitmap(tmpbitmap2);
  86.         generic_vh_stop();
  87.         return 1;
  88.     }
  89.  
  90.  
  91.     return 0;
  92. }
  93.  
  94.  
  95.  
  96. /***************************************************************************
  97.  
  98.   Stop the video hardware emulation.
  99.  
  100. ***************************************************************************/
  101. void blktiger_vh_stop(void)
  102. {
  103.     osd_free_bitmap(tmpbitmap2);
  104.     free(dirtybuffer2);
  105.     free(scroll_ram);
  106.     generic_vh_stop();
  107. }
  108.  
  109.  
  110.  
  111. WRITE_HANDLER( blktiger_background_w )
  112. {
  113.     offset += blktiger_scroll_bank;
  114.  
  115.     /* TODO: there's a bug lurking around. If I uncomment the following line, */
  116.     /* the intro screen doesn't work anymore (complete black instead of city landscape) */
  117. //    if (scroll_ram[offset] != data)
  118.     {
  119.         dirtybuffer2[offset] = 1;
  120.         scroll_ram[offset] = data;
  121.     }
  122. }
  123.  
  124.  
  125. WRITE_HANDLER( blktiger_scrollbank_w )
  126. {
  127.     blktiger_scroll_bank = (data & 0x03) * blktiger_backgroundram_size;
  128. }
  129.  
  130.  
  131. READ_HANDLER( blktiger_background_r )
  132. {
  133.     offset += blktiger_scroll_bank;
  134.     return scroll_ram[offset];
  135. }
  136.  
  137.  
  138. WRITE_HANDLER( blktiger_scrolly_w )
  139. {
  140.     blktiger_scrolly[offset]=data;
  141. }
  142.  
  143. WRITE_HANDLER( blktiger_scrollx_w )
  144. {
  145.     blktiger_scrollx[offset]=data;
  146. }
  147.  
  148.  
  149. WRITE_HANDLER( blktiger_video_control_w )
  150. {
  151.     /* bits 0 and 1 are coin counters */
  152.     coin_counter_w(0,data & 1);
  153.     coin_counter_w(1,data & 2);
  154.  
  155.     /* bit 5 resets the sound CPU - we ignore it */
  156.  
  157.     /* bit 6 flips screen */
  158.     blktiger_video_control=data;
  159.  
  160.     /* bit 7 enables characters? Just a guess */
  161.     chon = ~data & 0x80;
  162. }
  163.  
  164. WRITE_HANDLER( blktiger_video_enable_w )
  165. {
  166.     /* not sure which is which, but I think that bit 1 and 2 enable background and sprites */
  167.     /* bit 1 enables bg ? */
  168.     bgon = ~data & 0x02;
  169.  
  170.     /* bit 2 enables sprites ? */
  171.     objon = ~data & 0x04;
  172. }
  173.  
  174. WRITE_HANDLER( blktiger_screen_layout_w )
  175. {
  176.     screen_layout = data;
  177. }
  178.  
  179.  
  180.  
  181. /***************************************************************************
  182.  
  183.   Draw the game screen in the given osd_bitmap.
  184.   Do NOT call osd_update_display() from this function, it will be called by
  185.   the main emulation engine.
  186.  
  187. ***************************************************************************/
  188.  
  189. void blktiger_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  190. {
  191.     int offs, sx, sy;
  192.  
  193.  
  194. palette_init_used_colors();
  195.  
  196. {
  197.     int color,code,i;
  198.     int colmask[16];
  199.     int pal_base;
  200.  
  201.  
  202.     pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
  203.  
  204.     for (color = 0;color < 16;color++) colmask[color] = 0;
  205.  
  206.     for (offs = blktiger_backgroundram_size * scroll_page_count - 2;offs >= 0;offs -= 2)
  207.     {
  208.         int attr;
  209.  
  210.         attr = scroll_ram[offs + 1];
  211.         color = (attr & 0x78) >> 3;
  212.         code = scroll_ram[offs] + ((attr & 0x07) << 8);
  213.         colmask[color] |= Machine->gfx[1]->pen_usage[code];
  214.     }
  215.  
  216.     for (color = 0;color < 16;color++)
  217.     {
  218.         for (i = 0;i < 15;i++)
  219.         {
  220.             if (colmask[color] & (1 << i))
  221.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  222.         }
  223.         if (colmask[color] & (1 << 15))
  224.             palette_used_colors[pal_base + 16 * color + 15] = PALETTE_COLOR_TRANSPARENT;
  225.     }
  226. }
  227. for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  228. {
  229.     int colour,code,x;
  230.  
  231.  
  232.     sy = spriteram[offs + 2];
  233.     sx = spriteram[offs + 3] - ((spriteram[offs + 1] & 0x10) << 4);
  234.  
  235.     /* only count visible sprites */
  236.     if (sx+15 >= Machine->drv->visible_area.min_x &&
  237.             sx <= Machine->drv->visible_area.max_x &&
  238.             sy+15 >= Machine->drv->visible_area.min_y &&
  239.             sy <= Machine->drv->visible_area.max_y)
  240.     {
  241.         colour = spriteram[offs+1] & 0x07;
  242.         code=scroll_ram[offs];
  243.         code = spriteram[offs];
  244.         code += ( ((int)(spriteram[offs+1]&0xe0)) << 3 );
  245.         for (x = 0;x < 15;x++)
  246.         {
  247.             if (Machine->gfx[2]->pen_usage[code] & (1 << x))
  248.                 palette_used_colors[512 + 16 * colour + x] = PALETTE_COLOR_USED;
  249.         }
  250.     }
  251. }
  252. for (offs = videoram_size - 1;offs >= 0;offs--)
  253. {
  254.     int colour,code,x;
  255.  
  256.     colour = colorram[offs] & 0x1f;
  257.     code = videoram[offs] + ((colorram[offs] & 0xe0) << 3);
  258.     for (x = 0;x < 3;x++)
  259.     {
  260.         if (Machine->gfx[0]->pen_usage[code] & (1 << x))
  261.             palette_used_colors[768 + 4 * colour + x] = PALETTE_COLOR_USED;
  262.     }
  263. }
  264.  
  265.  
  266. if (palette_recalc())
  267.     memset(dirtybuffer2,1,blktiger_backgroundram_size * scroll_page_count);
  268.  
  269.  
  270.  
  271.     if (bgon)
  272.     {
  273.         /*
  274.         Draw the tiles.
  275.  
  276.         This method may look unnecessarily complex. Only tiles that are
  277.         likely to be visible are drawn. The rest are kept dirty until they
  278.         become visible.
  279.  
  280.         The reason for this is that on level 3, the palette changes a lot
  281.         if the whole virtual screen is checked and redrawn then the
  282.         game will slow down to a crawl.
  283.         */
  284.  
  285.         if (screen_layout)
  286.         {
  287.             /* 8x4 screen */
  288.             int offsetbase;
  289.             int scrollx,scrolly, y;
  290.             scrollx = ((blktiger_scrollx[0]>>4) + 16 * blktiger_scrollx[1]);
  291.             scrolly = ((blktiger_scrolly[0]>>4) + 16 * blktiger_scrolly[1]);
  292.  
  293.             for (sy=0; sy<18; sy++)
  294.             {
  295.                 y=(scrolly+sy)&(16*4-1);
  296.                 offsetbase=((y&0xf0)<<8)+32*(y&0x0f);
  297.                 for (sx=0; sx<18; sx++)
  298.                 {
  299.                     int colour, attr, code, x;
  300.                     x=(scrollx+sx)&(16*8-1);
  301.                     offs=offsetbase + ((x&0xf0)<<5)+2*(x&0x0f);
  302.  
  303.                     if (dirtybuffer2[offs] || dirtybuffer2[offs+1])
  304.                     {
  305.                         attr=scroll_ram[offs+1];
  306.                         colour=(attr&0x78)>>3;
  307.                         code=scroll_ram[offs];
  308.                         code+=256*(attr&0x07);
  309.  
  310.                         dirtybuffer2[offs] = dirtybuffer2[offs+1] = 0;
  311.  
  312.                         drawgfx(tmpbitmap2,Machine->gfx[1],
  313.                                 code,
  314.                                 colour,
  315.                                 attr & 0x80,0,
  316.                                 x*16, y*16,
  317.                                 0,TRANSPARENCY_NONE,0);
  318.                     }
  319.                 }
  320.             }
  321.  
  322.             /* copy the background graphics */
  323.             {
  324.                 scrollx = -(blktiger_scrollx[0] + 256 * blktiger_scrollx[1]);
  325.                 scrolly = -(blktiger_scrolly[0] + 256 * blktiger_scrolly[1]);
  326.                 copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  327.             }
  328.         }
  329.         else
  330.         {
  331.             /* 4x8 screen */
  332.             int offsetbase;
  333.             int scrollx,scrolly, y;
  334.             scrollx = ((blktiger_scrollx[0]>>4) + 16 * blktiger_scrollx[1]);
  335.             scrolly = ((blktiger_scrolly[0]>>4) + 16 * blktiger_scrolly[1]);
  336.  
  337.             for (sy=0; sy<18; sy++)
  338.             {
  339.                 y=(scrolly+sy)&(16*8-1);
  340.                 offsetbase=((y&0xf0)<<7)+32*(y&0x0f);
  341.                 for (sx=0; sx<18; sx++)
  342.                 {
  343.                     int colour, attr, code, x;
  344.                     x=(scrollx+sx)&(16*4-1);
  345.                     offs=offsetbase + ((x&0xf0)<<5)+2*(x&0x0f);
  346.  
  347.                     if (dirtybuffer2[offs] || dirtybuffer2[offs+1])
  348.                     {
  349.                         attr=scroll_ram[offs+1];
  350.                         colour=(attr&0x78)>>3;
  351.  
  352.                         code=scroll_ram[offs];
  353.                         code+=256*(attr&0x07);
  354.  
  355.                         dirtybuffer2[offs] = dirtybuffer2[offs+1] = 0;
  356.  
  357.                         drawgfx(tmpbitmap3,Machine->gfx[1],
  358.                                 code,
  359.                                 colour,
  360.                                 attr & 0x80,0,
  361.                                 x*16, y*16,
  362.                                 0,TRANSPARENCY_NONE,0);
  363.                     }
  364.                 }
  365.             }
  366.  
  367.             /* copy the background graphics */
  368.             {
  369.             scrollx = -(blktiger_scrollx[0] + 256 * blktiger_scrollx[1]);
  370.             scrolly = -(blktiger_scrolly[0] + 256 * blktiger_scrolly[1]);
  371.             copyscrollbitmap(bitmap,tmpbitmap3,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  372.             }
  373.         }
  374.     }
  375.     else fillbitmap(bitmap,palette_transparent_pen,&Machine->drv->visible_area);
  376.  
  377.  
  378.     if (objon)
  379.     {
  380.         /* Draw the sprites. */
  381.         for (offs = spriteram_size - 4;offs >= 0;offs -= 4)
  382.         {
  383.             /*    SPRITES
  384.                 =====
  385.                 Attribute
  386.                 0x80 Code MSB
  387.                 0x40 Code MSB
  388.                 0x20 Code MSB
  389.                 0x10 X MSB
  390.                 0x08 X flip
  391.                 0x04 Colour
  392.                 0x02 Colour
  393.                 0x01 Colour
  394.             */
  395.  
  396.             int code,colour;
  397.  
  398.             code = spriteram[offs];
  399.             code += ( ((int)(spriteram[offs+1]&0xe0)) << 3 );
  400.             colour = spriteram[offs+1] & 0x07;
  401.  
  402.             sy = spriteram[offs + 2];
  403.             sx = spriteram[offs + 3] - ((spriteram[offs + 1] & 0x10) << 4);
  404.  
  405.             drawgfx(bitmap,Machine->gfx[2],
  406.                     code,
  407.                     colour,
  408.                     spriteram[offs+1]&0x08,0,
  409.                     sx,sy,
  410.                     &Machine->drv->visible_area,TRANSPARENCY_PEN,15);
  411.         }
  412.     }
  413.  
  414.     if (chon)
  415.     {
  416.         /* draw the frontmost playfield. They are characters, but draw them as sprites */
  417.         for (offs = videoram_size - 1;offs >= 0;offs--)
  418.         {
  419.             sx = offs % 32;
  420.             sy = offs / 32;
  421.  
  422.             drawgfx(bitmap,Machine->gfx[0],
  423.                     videoram[offs] + ((colorram[offs] & 0xe0) << 3),
  424.                     colorram[offs] & 0x1f,
  425.                     0,0,
  426.                     8*sx,8*sy,
  427.                     &Machine->drv->visible_area,TRANSPARENCY_PEN,3);
  428.         }
  429.     }
  430. }
  431.